﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using MMOArpgServer.Pool;
namespace MMOArpgServer.Net
{
 public class ServerBase
    {
        private Socket _Socket;
        private IPAddress ipAdd;
        private IPEndPoint ipEP;
        private Semaphore _MaxClients;//线程池
        protected static int _currentClientID=0;
        public ServerBase(string ip,int port) {
            _Socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            ipAdd = IPAddress.Parse(ip);
            ipEP = new IPEndPoint(ipAdd, port);
            _Socket.Bind(ipEP);
            _Socket.Listen(1024);
            _MaxClients = new Semaphore(1024,1024);
            StartAccept(null);
        }

        private void StartAccept(SocketAsyncEventArgs accepteEventArgs)
        {
            //若为空则创建新的接收事件
            if (accepteEventArgs == null)
            {
                accepteEventArgs = new SocketAsyncEventArgs();
                accepteEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArgs_Completed);
            }
            else {
                //若已经创建了，将之前接收到的Socket置空
                accepteEventArgs.AcceptSocket = null;
            }
            _MaxClients.WaitOne();
            bool isWillRaiseEvent = _Socket.AcceptAsync(accepteEventArgs);
            if (!isWillRaiseEvent) {
                ProcessAccept(accepteEventArgs);
            }
        }

        private void AcceptEventArgs_Completed(object sender,SocketAsyncEventArgs eventArgs) {
            ProcessAccept(eventArgs);
        }
        private void ProcessAccept(SocketAsyncEventArgs eventArgs) {
            ClientToken tempToken = ClientPool.GetInstance().GetFreeClientToken();  
            tempToken.ServerBase = this;
            tempToken.Sokcet = eventArgs.AcceptSocket;
            tempToken.StartReceive();
            tempToken.AccountID = _currentClientID;
            StartAccept(eventArgs);
        }

    }
}
